//---------------------------------------------------------------------------------------------------------------------------------------------------------//
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
#include "Strings.h"

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
String::String():string(NULL) { }
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
String::String(const char* string) {
  if (string) {
    this->string = new char[strlen(string) + 1];
    strcpy(this->string, string);
  }
  else this->string = NULL;
}
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
String::String(const String* string) {
  if (string->string) {
    this->string = new char[strlen(string->string) + 1];
    strcpy(this->string, string->string);
  }
  else this->string = NULL;
}
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
String::String(const String& string) {
  if (string.string) {
    this->string = new char[strlen(string.string) + 1];
    strcpy(this->string, string.string);
  }
  else this->string = NULL;
}
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
String::String(String* string) {
  if (string->string) {
    this->string = new char[strlen(string->string) + 1];
    strcpy(this->string, string->string);
  }
  else this->string = NULL;
 }
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
String::String(String& string) {
  if (string.string) {
    this->string = new char[strlen(string.string) + 1];
    strcpy(this->string, string.string);
  }
  else this->string = NULL;
}
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
String::~String() {
  if (this->string) delete[] this->string;
}
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
void String::In(const char* string) {
  if (this->string) delete[] this->string;
  this->string = new char[strlen(string) + 1];
  strcpy(this->string, string);
}
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
void String::In(char* string) {
  if (this->string) delete[] this->string;
  this->string = new char[strlen(string) + 1];
  strcpy(this->string, string);
}
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
void String::In(char character, int position) {
  if (position >= strlen(this->string) || position < 0) return;
  this->string[position] = character;
}
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
void String::In(String* string) {
  if (!string) return;
  if (this->string) delete[] this->string;
  this->string = new char[strlen(string->string) + 1];
  strcpy(this->string, string->string);
}
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
void String::In(String& string) {
  if (this->string) delete[] this->string;
  this->string = new char[strlen(string.string) + 1];
  strcpy(this->string, string.string);
}
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
char *String::Out(void) {
  return this->string;
}
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
char String::Out(int position) {
  return this->string[position];
}
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
void String::Add(char character) {
  if (this->string) {
    char *temporal = this->string;
    this->string = new char[strlen(temporal) + 2];
    strcpy(this->string, temporal);
    this->string[strlen(temporal)] = character;
    this->string[strlen(temporal) + 1] = '\0';
    if (temporal) delete[] temporal;
  }
  else {
    this->string = new char[2];
    this->string[0] = character;
    this->string[1] = '\0';
  }
}
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
void String::Add(const char* string) {
  if (this->string) {
    char *temporal = this->string;
    this->string = new char[strlen(temporal) + strlen(string) + 1];
    strcpy(this->string, temporal);
    strcat(this->string, string);
    this->string[strlen(temporal) + strlen(string)] = '\0';
    if (temporal) delete[] temporal;
  }
  else {
    this->string = new char[strlen(string) + 1];
    strcpy(this->string, string);
    this->string[strlen(string)] = '\0';
  }
}
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
void String::Add(String* string) {
  if (!string) return;
  char *temporal = this->string;
  this->string = new char[strlen(temporal) + strlen(string->string) + 1];
  strcpy(this->string, temporal);
  strcat(this->string, string->string);
  this->string[strlen(temporal) + strlen(string->string)] = '\0';
  if (temporal) delete[] temporal;
}
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
void String::Add(String& string) {
  char *temporal = this->string;
  this->string = new char[strlen(temporal) + strlen(string.string) + 1];
  strcpy(this->string, temporal);
  strcat(this->string, string.string);
  this->string[strlen(temporal) + strlen(string.string)] = '\0';
  if (temporal) delete[] temporal;
}
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
void String::Add(int string) {
  char* temporal     = this->string;
  char* numberLength = new char[10000];
  sprintf(numberLength, "%d\0", string);
  this->string = new char[strlen(temporal) + strlen(numberLength) + 1];
  sprintf(this->string, "%s%d\0", temporal, string);
  if (temporal)     delete[] temporal;
  if (numberLength) delete[] numberLength;
}
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
void String::Add(long string) {
  char *temporal = this->string;
  char* numberLength = new char[10000];
  sprintf(numberLength, "%ld\0", string);
  this->string = new char[strlen(temporal) + strlen(numberLength) + 1];
  sprintf(this->string, "%s%ld\0", temporal, string);
  if (temporal)     delete[] temporal;
  if (numberLength) delete[] numberLength;
}
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
void String::Add(float string) {
  char *temporal = this->string;
  char* numberLength = new char[10000];
  sprintf(numberLength, "%f\0", string);
  this->string = new char[strlen(temporal) + strlen(numberLength) + 1];
  sprintf(this->string, "%s%f\0", temporal, string);
  if (temporal)     delete[] temporal;
  if (numberLength) delete[] numberLength;
}
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
void String::Add(double string) {
  char *temporal = this->string;
  char* numberLength = new char[10000];
  sprintf(numberLength, "%f\0", string);
  this->string = new char[strlen(temporal) + strlen(numberLength) + 1];
  sprintf(this->string, "%s%f\0", temporal, string);
  if (temporal)     delete[] temporal;
  if (numberLength) delete[] numberLength;
}
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
void String::Insert(char character, int position) {
  if (position < 0 || position >= strlen(this->string) || !this->string)
    return;
  this->string[position] = character;
}
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
void String::Insert(char* inString, int position) {
  if (!inString || position < 0 || position >= strlen(this->string) || !this->string)
    return;
  char *temporal = this->string;
  if ((position + strlen(inString)) >= strlen(this->string))
    this->string = new char[position + strlen(inString) + 1];
  for (int i = position, j = 0; i < (position + strlen(inString)); i++)
    this->string[i] = inString[j++];
  if (temporal) delete[] temporal;
}
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
void String::Insert(String& inString, int position) {
  if (!(inString.string) || position < 0 || position >= strlen(this->string) || !this->string)
    return;
  char *temporal = this->string;
  if ((position + inString.Length()) >= strlen(this->string))
    this->string = new char[position + inString.Length() + 1];
  for (int i = position, j = 0; i < (position + inString.Length()); i++)
    this->string[i] = (inString.Out())[j++];
  if (temporal) delete[] temporal;
}
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
void String::Insert(String* inString, int position) {
  if (!(inString->string) || position < 0 || position >= strlen(this->string) || !this->string)
    return;
  char *temporal = this->string;
  if ((position + inString->Length()) >= strlen(this->string))
    this->string = new char[position + inString->Length() + 1];
  for (int i = position, j = 0; i < (position + inString->Length()); i++)
    this->string[i] = (inString->Out())[j++];
  if (temporal) delete[] temporal;
}
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
long String::Length(void) {
  return (this->string)?strlen(this->string):0;
}
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
bool String::Contain(const char *string) {
  return (strstr(this->string, string))?true:false;
}
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
bool String::Contain(String* string) {
  if (!string) return false;
  return (strstr(this->string, string->string))?true:false;
}
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
bool String::Contain(String& string) {
  return (strstr(this->string, string.string))?true:false;
}
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
String* String::SubStr(int initPos, int endPos) {
  if (initPos < 0 || endPos > strlen(this->string)) return NULL;
  String *temporal = new String();
  for (int i = initPos; i < endPos; i++)
    temporal->Add(this->string[i]);
  temporal->Add('\0');
  return temporal;
}
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
int String::Count(const char *string) {
  if (!string) return 0;
  int count = 0;
  for (int i = 0; i < strlen(string); i++)
    for (int j = 0; j < strlen(this->string); j++)
      if (string[i] == this->string[j]) count++;
  return count;
}
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
int String::Count(String* string) {
  if (!string->Out()) return 0;
  int count = 0;
  for (int i = 0; i < strlen(string->Out()); i++)
    for (int j = 0; j < strlen(this->string); j++)
      if (string->Out()[i] == this->string[j]) count++;
  return count;
}
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
int String::Count(String& string) {
  if (!string.Out()) return 0;
  int count = 0;
  for (int i = 0; i < strlen(string.Out()); i++)
    for (int j = 0; j < strlen(this->string); j++)
      if (string.Out()[i] == this->string[j]) count++;
  return count;
}
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
int String::CountAlpha(void) {
  int count = 0;
  for (int i = 0; i < strlen(this->string); i++)
    if (isalpha(this->string[i])) count++;
  return count;
}
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
void String::Trim(void) {
  int i, j;
  for (i = 0, j = 0; i < strlen(this->string); i++)
    if ((this->string[i] != '\n') && (this->string[i] != '\r') && (this->string[i] != EOF))
      this->string[j++] = this->string[i];
  this->string[j] = '\0';
}
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
void String::RTrim(void) {
  int i, j;
  for (i = 0, j = 0; i < strlen(this->string); i++)
    if ((this->string[i] != '\n') && (this->string[i] != '\r') && (this->string[i] != '\t') && (this->string[i] != ' ') && (this->string[i] != EOF))
      this->string[j++] = this->string[i];
  this->string[j] = '\0';
}
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
void String::ITrim(void) {
  int  i, j;
  bool condition = false;
  for (i = 0, j = 0; i < strlen(this->string); i++) 
    if ((this->string[i] != '\n') && (this->string[i] != '\r') && (this->string[i] != EOF)) {
      if ((this->string[i] == ' ') && condition)
        this->string[j++] = this->string[i];
      if ((this->string[i] != ' ')) {
        this->string[j++] = this->string[i];
        condition         = true;
      }
    }
  this->string[j] = '\0';
}
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
void String::ToUpper(void) {
  if (!this->string) return;
  for (int i = 0; i < strlen(this->string); i++)
    this->string[i] = (char)toupper(this->string[i]);
}
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
void String::ToLower(void) {
  if (!this->string) return;
  for (int i = 0; i < strlen(this->string); i++)
    this->string[i] = (char)tolower(this->string[i]);
}
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
char* String::ToString(void) {
  return this->string;
}
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
String* String::Cut(int initial, int size) {
  if (!this->string || (initial + size) > strlen(this->string)) return this;
  char* tmp = new char[size + 1];
  strncpy(tmp, (this->string + initial), size);
  tmp[size] = '\0';
  if (this->string) delete[] this->string;
  this->string = tmp;
  return this;
}
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
String String::operator=(const char* string) {
  if (this->string) delete[] this->string;
  this->string = new char[strlen(string) + 1];
  strcpy(this->string, string);
  return *this;
}
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
String String::operator=(char* string) {
  if (this->string) delete[] this->string;
  this->string = new char[strlen(string) + 1];
  strcpy(this->string, string);
  return *this;
}
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
String String::operator=(const String& string) {
  if (this->string) delete[] this->string;
  this->string = new char[strlen(string.string) + 1];
  strcpy(this->string, string.string);
  return *this;
}
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
bool String::operator>(const char* string) {
  if (!this->string || !string) return false;
  return (strcmp(this->string, string) > 0)?true:false;
}
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
bool String::operator>(String& string) {
  if (!this->string || !string.string) return false;
  return (strcmp(this->string, string.string) > 0)?true:false;
}
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
bool String::operator<(const char* string) {
  if (!this->string || !string) return false;
  return (strcmp(this->string, string) < 0)?true:false;
}
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
bool String::operator<(String& string) {
  if (!this->string || !string.string) return false;
  return (strcmp(this->string, string.string) < 0)?true:false;
}
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
bool String::operator!() {
  return (this->string)?false:true;
}
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
bool String::operator==(const char* string) {
  if (!this->string || !string) return false;
  return (strcmp(this->string, string) == 0)?true:false;
}
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
bool String::operator==(String& string) {
  if (!this->string || !string.string) return false;
  return (strcmp(this->string, string.string) == 0)?true:false;
}
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
bool String::operator!=(const char* string) {
  if (!this->string || !string) return false;
  return (strcmp(this->string, string) != 0)?true:false;
}
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
bool String::operator!=(String& string) {
  if (!this->string || !string.string) return false;
  return (strcmp(this->string, string.string) != 0)?true:false;
}
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
char* String::operator+(const char* string) {
  char *temporal = this->string;
  this->string = new char[strlen(temporal)+ strlen(string) + 1];
  strcpy(this->string, temporal);
  strcat(this->string, string);
  this->string[strlen(temporal)+ strlen(string)] = '\0';
  if (temporal) delete[] temporal;
  return this->string;
}
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
String String::operator+(String& string) {
  char *temporal = this->string;
  this->string = new char[strlen(temporal)+ strlen(string.string) + 1];
  strcpy(this->string, temporal);
  strcat(this->string, string.string);
  this->string[strlen(temporal)+ strlen(string.string)] = '\0';
  if (temporal) delete[] temporal;
  return *this;
}
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
char String::operator[](int position) {
  if (position >= strlen(this->string) || position < 0) return ' ';
  return this->string[position];
}
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
